//*********************************************************************
// Copyright (C) 2014 Hell Prototypes / www.hellprototypes.com
// 
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or (at
// your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
//********************************************************************

#include <avr/io.h>
#include "common.h"


#define I2C_MOD_EN		0

//I2C pin
#define I2C_SCL				1
#define I2C_SDA				0

#define PIN_LOW(pin)		clrbit(GPIO_H_OUT, pin)
#define PIN_HIGH(pin)		setbit(GPIO_H_OUT, pin)

#define PIN_INPUT(pin)		clrbit(PORTE.DIR, pin)
#define PIN_OUTPUT(pin)	setbit(PORTE.DIR, pin)

#define i2c_nop() 

#define SET_SCL()			do{ PIN_HIGH(I2C_SCL); i2c_nop(); }while(0)
#define CLR_SCL()			do{ PIN_LOW(I2C_SCL);  i2c_nop(); }while(0)

#define SET_SDA()			do{ PIN_HIGH(I2C_SDA); i2c_nop(); }while(0)
#define CLR_SDA()			do{ PIN_LOW(I2C_SDA);  i2c_nop(); }while(0)

#define GET_SDA()			testbit(PORTE.IN, I2C_SDA)

void l_delay(void)
{
	_delay_us(50);
}

void ext_i2c_start(void)
{
	PIN_OUTPUT(I2C_SCL);
	PIN_OUTPUT(I2C_SDA);
	SET_SDA();
	SET_SCL();

	l_delay();
	CLR_SDA();
	l_delay();
	CLR_SCL();
	l_delay();
	CLR_SCL();
}

void ext_i2c_stop(void)
{
	//CLR_SCL();
	CLR_SDA();
	PIN_OUTPUT(I2C_SCL);
	PIN_OUTPUT(I2C_SDA);
	l_delay();
	SET_SCL();
	l_delay();
	SET_SDA();
}

unsigned char ext_i2c_write(unsigned char data)
{
	unsigned char mask = 0x80, ret;

	PIN_OUTPUT(I2C_SDA);
	do {
		if(mask & data) {
			SET_SDA();
		} else {
			CLR_SDA();
		}
		l_delay();
		SET_SCL();
		l_delay();
		mask = mask >> 1;
		CLR_SCL();
	} while(mask);
	SET_SDA();
	PIN_INPUT(I2C_SDA);

	l_delay();
	SET_SCL();
	l_delay();
	ret = GET_SDA();
	CLR_SCL();
	l_delay();

	return ret;
}

unsigned char ext_i2c_read(unsigned char ack_en)
{
	unsigned char mask = 0x80, read = 0;

	do {
		SET_SCL();
		if(GET_SDA()) {
			read |= mask;
		}
		l_delay();
		mask = mask >> 1;
		CLR_SCL();
		l_delay();
	} while(mask);

	//ACK
	if(ack_en) {
		CLR_SDA();
	} else {
		SET_SDA();
	}
	PIN_OUTPUT(I2C_SDA);
	l_delay();
	SET_SCL();
	l_delay();
	CLR_SCL();
	SET_SDA();
	PIN_INPUT(I2C_SDA);
	l_delay();

	return read;
}

